home *** CD-ROM | disk | FTP | other *** search
- Listing 2
-
-
- /* ----------------------------------------------------------- */
-
- #include <stdio.h>
-
- typedef struct node {
- char value;
- struct node *left_child;
- struct node *right_child;
- } Node;
-
- void prt_tree_prefix_order(Node *tree);
- void prt_tree_infix_order(Node *tree);
- void prt_tree_postfix_order(Node *tree);
-
- void push(Node *value);
- Node *pop(void);
-
- /* ----------------------------------------------------------- */
-
- main()
- {
- static Node tree[] = {
- {'*', &tree[1], &tree[2]}, /* [0] */
- {'+', &tree[3], &tree[4]}, /* [1] */
- {'-', &tree[5], &tree[6]}, /* [2] */
- {'A', NULL, NULL}, /* [3] */
- {'B', NULL, NULL}, /* [4] */
- {'C', NULL, NULL}, /* [5] */
- {'/', &tree[7], &tree[8]}, /* [6] */
- {'D', NULL, NULL}, /* [7] */
- {'E', NULL, NULL} /* [8] */
- };
-
- prt_tree_prefix_order(tree);
- prt_tree_infix_order(tree);
- prt_tree_postfix_order(tree);
-
- return 0;
- }
-
- /* --------------------------------------------------------------
-
- PRT_TREE_PREFIX_ORDER: The steps to traverse a binary tree in prefix
- order and to display the value of each node are:
-
- A. Initialize a pointer to the root of the tree.
-
- B. Push a null sentinel on the stack.
-
- C. Process the whole tree (until we run into the null sentinel we
- placed on the stack in Step B. We do this by going down the left
- branch as far as we can, then down the right branch until we come
- to another left branch.
-
- D. Display node's value.
-
- E. If the current node has a right branch push the pointer to that
- branch on the stack.
-
- F. If the current node has a left branch follow that branch.
-
- G. If the current node is a leaf (terminal) node or has no left
- branch, pop a saved (right branch) value back off the stack
- and start traversing the subtree to the right.
-
- -------------------------------------------------------------- */
-
- void prt_tree_prefix_order(Node *tree)
- {
- /*A*/ const Node *ptr = tree;
-
- /*B*/ push(NULL);
-
- /*C*/ while (ptr != NULL) {
- /*D*/ printf("%c", ptr->value);
- /*E*/ if (ptr->right_child != NULL) {
- push(ptr->right_child);
- }
- /*F*/ if (ptr->left_child != NULL) {
- ptr = ptr->left_child;
- }
- /*G*/ else {
- ptr = pop();
- }
- }
- putchar('\n');
- }
-
- /* --------------------------------------------------------------
-
- PRT_TREE_INFIX_ORDER: The steps to traverse a binary tree in infix
- order and to display the value of each node are:
-
- A. Initialize a pointer to the root of the tree.
-
- B. Push a null sentinel on the stack.
-
- C. Push the whole left subtree on the stack.
-
- D. Start backtracking by popping off last node pushed.
-
- E. Backtrack until we run into the sentinel placed on the stack in
- Step B.
-
- F. Display node's value.
-
- G. If the current node has a right branch follow that branch and go
- to Step C.
-
- H. Pop the next node off stack.
-
- -------------------------------------------------------------- */
-
- void prt_tree_infix_order(Node *tree)
- {
- /*A*/ Node *ptr = tree;
-
- /*B*/ push(NULL);
-
- /*C*/
- loop: while (ptr != NULL) {
- push(ptr);
- ptr = ptr->left_child;
- }
-
- /*D*/ ptr = pop();
- /*E*/ while (ptr != NULL) {
- /*F*/ printf("%c", ptr->value);
- /*G*/ if (ptr->right_child != NULL) {
- ptr = ptr->right_child;
- goto loop;
- }
- /*H*/ ptr = pop();
- }
- putchar('\n');
- }
-
- /* --------------------------------------------------------------
-
- PRT_TREE_POSTFIX_ORDER: The steps to traverse a binary tree in postfix
- order and to display the value of each node are:
-
- A. Initialize a pointer to the root of the tree.
-
- B. Push a null sentinel on the stack.
-
- C. Push the whole left subtree on the stack.
-
- D. Push current node pointer on stack.
-
- E. If the current node has a right branch push the pointer to that
- branch on the stack and also push a special marker. This is
- achieved by allocating a dummy variable `marker' so we can use its
- address as a unique special pointer.
-
- F. Follow the left branch.
-
- G. Pop a pointer off stack.
-
- H. Display node's value and keep popping off the stack until we
- either run into the null sentinel (end of stack) or the special
- marker.
-
- I. If we found a special marker, pop the associated pointer and go to
- Step C. Otherwise, we must have reached the null sentinel so we're
- done.
-
- -------------------------------------------------------------- */
-
- void prt_tree_postfix_order(Node *tree)
- {
- /*A*/ Node *ptr = tree;
- Node marker;
-
- /*B*/ push(NULL);
-
- /*C*/
- loop: while (ptr != NULL) {
- /*D*/ push(ptr);
- /*E*/ if (ptr->right_child != NULL) {
- push(ptr->right_child);
- push(&marker);
- }
- /*F*/ ptr = ptr->left_child;
- }
- /*G*/ ptr = pop();
- /*H*/ while (ptr != NULL && ptr != &marker) {
- printf("%c", ptr->value);
- ptr = pop();
- }
- /*I*/ if (ptr == &marker) {
- ptr = pop();
- goto loop;
- }
- putchar('\n');
- }
-
- /* ----------------------------------------------------------- */
-
- #define STACK_SIZE 30
-
- static Node *stack[STACK_SIZE];
-
- static size_t stack_ptr = 0;
-
- void push(Node *value)
- {
- if (stack_ptr == STACK_SIZE)
- printf("Stack is full\n");
- else
- stack[stack_ptr++] = value;
- }
-
- Node *pop(void)
- {
- if (stack_ptr == 0) {
- printf("Stack is empty\n");
- return 0;
- }
-
- return stack[--stack_ptr];
- }
-
- /* ----------------------------------------------------------- */
-
-